/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.mabi.modular.install.modules;

import ClassMonger.ClassMonger;
import com.mabi.modular.runtime.application.IFrontEndApp;
import com.mabi.modular.runtime.module.contributions.actions.AbstractMabiAction;
import com.mabi.modular.runtime.module.contributions.views.ViewImpl;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractAction;

/**
 *
 * @author User
 */
public abstract class ModuleDefinition implements IModuleDefinition {

    private String moduleName;
    private String moduleJndiKey;
    private String moduleVersion;
    private String moduleDescription;

    //public abstract List<AbstractMabiAction> getActions();
    protected IFrontEndApp frontEndApp;
    protected List<Class<ViewImpl>> views = new ArrayList();
    protected List<Class<AbstractAction>> actions = new ArrayList();
    private Class[] classesFoundInModule = null;
    protected Properties config = null;

    @Override
    public void setAppication(IFrontEndApp app) {
        frontEndApp = app;
    }

    public IFrontEndApp getFrontEndApp() {
        return frontEndApp;
    }

    @Override
    public void initializeModule() {
        System.out.println("INITIALIZING DEFINITION FOR MODULE " + getModuleName() + " WITH APPLICATION " + frontEndApp.getMainWindow().getCaption());
    }

    @Override
    public List<Class<ViewImpl>> getViews() {
        return views;
    }

    @Override
    public String getModuleName() {
        return moduleName;
    }

    @Override
    public String getModuleDescription() {
        return moduleDescription;
    }

    @Override
    public float getModuleVersion() {
        return Float.parseFloat(moduleVersion);
    }

    @Override
    public String getModuleJndiKey() {
        return moduleJndiKey;
    }
    
    @Override
    public List<Class<AbstractMabiAction>> getActions(){
        return null;
    }

    /**
     * Constructor that starts the module instalation process
     */
    public ModuleDefinition() {
        try {
            loadConfiguration();
            initializeModuleData();
            initializeModuleContent();
            loadViews();
            loadActions();
            subscribeModule();
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(ModuleDefinition.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(ModuleDefinition.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            Logger.getLogger(ModuleDefinition.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Finds all the views, instantiate them and puts them in a collection
     */
    private void initializeModuleContent() throws IOException, ClassNotFoundException {
        classesFoundInModule = ClassMonger.getClasses(this.getClass().getPackage().getName(), this.getClass().getClassLoader());
    }

    private void loadViews() {
        Class viewClass = ViewImpl.class;
        for (Class class1 : classesFoundInModule) {
            if (class1.getSuperclass() == viewClass) {
                views.add(class1);
            }
        }
    }

    private void loadActions() {
        Class actionClass = AbstractAction.class;
        for (Class class1 : classesFoundInModule) {
            if (class1.getSuperclass() == actionClass) {
                actions.add(class1);
            }
        }
    }

    private void subscribeModule() throws Exception {
        String moduleConfigString = "";
        if (config.getProperty("JNDI_KEY") == null || config.getProperty("MODULE_NAME") == null || config.getProperty("MODULE_VERSION") == null) {
            throw new Exception("Malformed module configuration file");
        }
        String key = "JNDI_KEY=>" + moduleJndiKey + ",";// config.getProperty("JNDI_KEY") + ",";
        String name = "MODULE_NAME=>" + moduleName + ",";// config.getProperty("MODULE_NAME") + ",";
        String version = "MODULE_VERSION=>" + moduleVersion;// config.getProperty("MODULE_VERSION");
        moduleConfigString = key + name + version;
        System.setProperty("module_" + name, moduleConfigString);
    }

    private void loadConfiguration() throws IOException {
        String configUri = "/" + this.getClass().getPackage().getName().replace(".", "/") + "/config.properties";
        if (config == null) {
            config = new Properties();
        }
        config.load(this.getClass().getClassLoader().getResourceAsStream(configUri));
    }

    private void initializeModuleData() {
        moduleName = config.getProperty("MODULE_NAME");
        moduleJndiKey = config.getProperty("JNDI_KEY");
        moduleVersion = config.getProperty("MODULE_VERSION");
        moduleDescription = config.getProperty("MODULE_DESCRIPTION");
    }
}
